﻿using System;
using System.ComponentModel;
using System.Windows.Forms;

using BizElements.Core;

namespace BizElements.Generator
{
    public partial class SQLiteConnCtl : UserControl, IMetaDataSourceUi
    {
        public SQLiteConnCtl()
        {
            InitializeComponent();
        }

        private void uiOpenFile_Click(object sender, EventArgs e)
        {
            var answer = this.uiDatabaseFile.ShowDialog();
            if (answer == DialogResult.OK)
            {
                this.uiFilePath.Text = this.uiDatabaseFile.FileName;
            }
        }

        #region Connect - parse and test metadata source.

        private void uiConnect_Click(object sender, EventArgs e)
        {
            CreateAndTestNewMetaDataSource();
        }

        private void CreateAndTestNewMetaDataSource()
        {
            var connStr = ParseConnectionString();
            if (connStr == null)
                return;

            this.MetaDataSource = DbGeneratorComponentFactory.GetMetadataSource(this.dbms, connStr);
            bool isTestOk = TestConnection();
            if (isTestOk)
            {
                FireConnected();
                this.uiConnect.Enabled = false;
                this.uiDisconnect.Enabled = true;
            }
            else
            {
                this.MetaDataSource = null;
            }
        }

        const string ConnStringFormat = @"Data Source={0}";

        private string ParseConnectionString()
        {
            string path = this.uiFilePath.Text.Trim();
            if (string.IsNullOrEmpty(path))
                return null;
            else
                return string.Format(ConnStringFormat, path);
        }

        private bool TestConnection()
        {
            try
            {
                this.Cursor = Cursors.AppStarting;
                this.MetaDataSource.OpenConnection();
                this.MetaDataSource.CloseConnection();
                return true;
            }
            catch (Exception ex)
            {
                string errmsg = Messages.SQLiteConnCtl_CannotConnectToDatabase + Environment.NewLine + ex.ToString();
                MessageBox.Show(errmsg, Messages.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void FireConnected()
        {
            if (this.Connected != null)
                Connected(this, new MetaDataSourceEventArgs(this.MetaDataSource));
        }

        #endregion

        #region Disconnect and dispose metadata source.

        private void uiDisconnect_Click(object sender, EventArgs e)
        {
            DisconnectAndDisposeCurrentMetaDataSource();
        }

        private void DisconnectAndDisposeCurrentMetaDataSource()
        {
            DisposeCurrentMetaDataSource();
            this.uiConnect.Enabled = true;
            this.uiDisconnect.Enabled = false;
            FireDisconnected();
        }

        private void FireDisconnected()
        {
            if (this.Disconnected != null)
                Disconnected(this, null);
        }

        private void DisposeCurrentMetaDataSource()
        {
            if (this.MetaDataSource != null)
            {
                this.MetaDataSource.CloseConnection();
                this.MetaDataSource = null;
            }
        }

        #endregion

        #region IMetaDataSourceUi Members.

        [Browsable(false)]
        public UserControl Control
        {
            get { return this; }
        }

        [Browsable(false)]
        public IMetadataSource MetaDataSource { get; private set; }

        DbmsType dbms = DbmsType.SQLite_3;

        public DbmsType Dbms
        {
            get { return this.dbms; }
            set
            {
                if (DbGeneratorComponentFactory.IsSQLite(value))
                    this.dbms = value;
                else
                    throw new ArgumentException(Messages.SQLiteConnCtl_OnlySQLiteDBMSsAreSupported);
            }
        }

        public event EventHandler<MetaDataSourceEventArgs> Connected;

        public event EventHandler<MetaDataSourceEventArgs> Disconnected;

        #endregion

        #region Settings.

        public void ReadSettings(BizElementsSettings settings)
        {
            DisconnectAndDisposeCurrentMetaDataSource();
            this.uiFilePath.Text = settings["SQLiteConn_DbFilePath"];
        }

        public void WriteSettings(BizElementsSettings settings)
        {
            settings["SQLiteConn_DbFilePath"] = this.uiFilePath.Text.Trim();
        }

        #endregion
    }
}
